import greenfoot.*;
import java.util.List;
import java.lang.Math;

/**
 * Unidad de combate
 */
public abstract class Unidad extends Actor
{
    public enum Color { ROJO, VERDE, GRIS };
    public enum Accion { MOVER, CAPTURAR, ATACAR };
    
    protected Color color;
    protected Accion acc;
    
    protected boolean jugador; //controlada por el jugador?
    
    protected Unidad objetivo; //enemigo para atacar
    protected int objx = -1, objy = -1; //posicion para moverse
    
    protected int vida; 
    int velocidad=10;
    
    public Unidad( Color col, boolean jugador ){
        this.color = col; this.jugador = jugador;
//        if(!jugador)
            acc = Accion.ATACAR;
    }
    
    public void act(){       
        if( acc == Accion.MOVER || acc == Accion.CAPTURAR )
        {
            turnTowards( objx, objy );
            move(velocidad);
            if( distancia( objx, objy ) <= 10 )
                acc = Accion.ATACAR;
        } else if( acc == Accion.ATACAR )
        {
//            if(!jugador)
                setObjetivo();
            
            if( objetivo != null  &&  objetivo.getWorld() != null ){
                if( enRango( objetivo ) ){
                    atacar();
                } else {
                    haciaObjetivo();
                }
            }
        }
    }
    
    public void nuevoObjetivo(Unidad u){
        objetivo = u;
    }
    
    private void setObjetivo(){
        if( objetivo != null  &&  objetivo.getWorld() == null )
            objetivo = null;
        List<Unidad> unidades = getWorld().getObjects( Unidad.class );
        for( Unidad u: unidades ){
            if( u.color == color )  continue;
            if( objetivo != null  &&  distancia(u) < distancia(objetivo) ){
                objetivo = u;
            } else if( objetivo == null ){
                objetivo = u;
            }
        }
    }
    
    protected abstract boolean enRango( Unidad u );
    
    protected void haciaObjetivo(){
        turnTowards( objetivo.getX(), objetivo.getY() );
        move(velocidad);
    }
    
    protected double distancia( int x, int y )
    {
        int dx = x - getX();
        int dy = y - getY();
        return Math.sqrt( dx*dx + dy*dy );   
    }
    
    protected double distancia( Unidad u ) {
        int dx = u.getX() - getX();
        int dy = u.getY() - getY();
        return Math.sqrt( dx*dx + dy*dy );
    }
    
    /**
     * Girar hacia el objetivo.
     */
    protected void apuntar(){
        turnTowards( objetivo.getX(), objetivo.getY() );
    }
    
    protected abstract void atacar();
    
    public void bajarVida( int puntosVida ){
        vida -= puntosVida;
        if( vida <= 0 ){
            getWorld().removeObject( this );
            muere();
        }
    }
    
    protected abstract void muere();
    
    Actor getOneIntersectingObjectPlease(java.lang.Class cls)
    {
        return getOneIntersectingObject(cls);
    }
    
    void disparar()
    {
        GreenfootImage img = objetivo.getImage();
        int w = img.getWidth()/2;
        int h = img.getHeight()/2;
        int x = objetivo.getX();
        int y = objetivo.getY();
        int d = (int)(distancia(objetivo)/15);
        getWorld().addObject( new ImpactoBala(), x-w-d+Greenfoot.getRandomNumber(w*2+d*2),
            y-h-d+Greenfoot.getRandomNumber(h*2+d*2)); 
    }
}
